/*
 * Copyright 2020-2025 the original author or authors.
 * You cannot use this file unless authorized by the author.
 */

package org.ipig.commons.service.lock.impl;

import org.ipig.commons.service.lock.LockService;
import org.ipig.data.redis.RedisManager;
import lombok.Data;
import org.apache.commons.lang3.StringUtils;
import redis.clients.jedis.Jedis;

/**
 * 分布式锁服务实现
 *
 * @author <a href="mailto:comchnts@163.com">chinats</a>
 * @version $$Id: RedisDistLockServiceImpl.java 3 2020-01-21 09:36:33Z ts <comchnts@163.com> $$
 * @since 1.0
 */
@Data
public class RedisDistLockServiceImpl implements LockService {
    private RedisManager redisManager;

    @Override
    public boolean lock(String key, long expireMillis) {
        long value = System.currentTimeMillis() + expireMillis;
        Jedis jedis = null;
        try {
            jedis = redisManager.getDefaultResource();
            if (jedis != null) {
                long status = jedis.setnx(key, String.valueOf(value));
                if (status == 1) {
                    return true;
                }
                long oldExpireTime = Long.parseLong(StringUtils.defaultIfBlank(jedis.get(key), "0"));
                if (oldExpireTime < System.currentTimeMillis()) {
                    //超时
                    long newExpireTime = System.currentTimeMillis() + expireMillis;
                    long currentExpireTime = Long.parseLong(jedis.getSet(key, String.valueOf(newExpireTime)));
                    if (currentExpireTime == oldExpireTime) {
                        return true;
                    }
                }
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        } finally {
            if (jedis != null) {
                redisManager.returnResource(jedis);
            }
        }
        return false;
    }

    @Override
    public void unlock(String key) {
        Jedis jedis = null;
        try {
            jedis = redisManager.getDefaultResource();
            if (jedis != null) {
                long oldExpireTime = Long.parseLong(StringUtils.defaultIfBlank(jedis.get(key), "0"));
                if (oldExpireTime > System.currentTimeMillis()) {
                    jedis.del(key);
                }
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        } finally {
            if (jedis != null) {
                redisManager.returnResource(jedis);
            }
        }
    }
}
